iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0
Modern Web

想轉職的鯊魚從零基礎開始學習JavaScript系列 第 6

想轉職的鯊魚從零基礎開始學習JavaScript Day-06 number、bigint與boolean

  • 分享至 

  • xImage
  •  

數字

JavaScript數字分類比較簡約,不像一般的程式語言不同,數字能再細分成

Floating(浮點數型)、Integers(整數型)、double(雙精度型)或是Bignum(大數型)

JavaScript只有兩種,分別是number跟bigint,接下來讓鯊魚來一一介紹。

number

  • 所有數字
  • Infinity/-Infinity
  • NaN(Not a Number)

數字

number是使用雙精度浮點數(double)儲存的數值,他的精確度可以到正負2的53次方-1(2**53-1)

在這之上精確度會失準,用常見的等式來說明

// 2**53-1以內時
2**53-1 === 2**53-2
// 可以精確的回報false
// 可是當你超過2**53-1時
2**53 === 2**53+1
// 此時卻回報了true
2**53+2 === 2**53+3
// 而此時卻回報了false

會有這樣的結果是因為他超出雙精度浮點數的精確度範圍了,

也就是超出2的53次方以上了,沒辦法判斷如此的精確

而且超出越多精確度越差,另外number一次只能處理16位數

超出的部分會從後面以0代替,而進位與否要看浮點數的精確度比較偏向哪一邊

360287970189639765
// 輸入上的超過16位數的數字
360287970189639740
// 回傳的數字比輸出少了15

由上面的例子可以看出16位之後65,因為浮點數的精確度問題而跟輸出的值有所出入

所以當你有必須使用到超過2的53次方的數字請使用下面介紹的bigint型別。

無法完善處理的小數

先前我們提到number是使用雙精度浮點數(double)儲存的數值

值往上超過2的53次方會失去精準,而因為儲存方式的關係

十進位制的小數無法用二進位完美的呈現

所以小數的運算會出現一些無法預期的錯誤

0.2 + 0.4 ===0.6
// false 

因為儲存方式的關係,小數會有一些的精度誤差,如果要做小數的運算

建議先轉成整數在做運算,雖然會碰到大雖然有機會碰到bigint超出範圍的狀況

十進位之外的數字

除了十進位之外,JavaScript還支援16及2進位,

0xaf
// 175 16進位
0b11
// 3 2進位

8進位在ECMAScript標準未支援,但是某些可以實作,有些不行,

所以不建議使用,因為無法確定,這是會被當作10進位還是8進位使用

而導致出現無法預期的結果

Infinity/-Infinity

此外,因為number是使用雙精度浮點數(double)儲存的數值,

所以他的最大上/下限便是正/負2的1024次方,但bigint可以超出這範圍

2**1024
// Infinity
-(2**1024)
// -Infinity

NaN(Not a Number)

從字面上來看,他不是個數字,但是用typeof NaN鑑定

他又會回傳是一個數字,那他到底是是什麼呢?

鯊魚個人的解釋是這樣的:

在應該回傳的數字的結果中,出現了不是數字的結果這時就會回傳NaN

就像是

Number("String")
// NaN

Number()理應回傳一個數字,但是"String"無法轉變成數字

所以只好回傳一個數字型別的NaN來表示"String"無法被變成數字

NaN是一個相當獨特的存在,他不是任何人包含他自己

所以 NaN 不等於 NaN

NaN !== NaN
// true

因此產生了一個專門判斷NaN的東西 isNaN(),在寫判斷式的時候很好用

isNaN(NaN)
// true

另外任何數字遇上NaN都會被NaN併吞,最後只會剩下NaN

就像鯊魚會吞噬獵物,最後只會剩下鯊魚

20+NaN
// NaN

bigint

bigint字面上來說就是大整數(big Integers)專門處理超過2的53次方的數字

轉成這種型別很簡單

  • 數字後面加一個n,例如9527n
  • BigInt()裡面放數字,例如BigInt(9527)

像下面這樣

9527n
// 9527n
BigInt(9527)
// 9527n

面對大數字的時候跟number的差別

3602879701896397652
// 3602879701896398000
3602879701896397652n
// 3602879701896397652n
// 之前number無法完整呈現的數字,用bigint就能完整呈現了

但是bigint雖然可以處理大數字的運算,但是他的不能跟其他類型混用,除了字串

20n + 2
// Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions at <anonymous>:1:5
// BigInt不能跟其他類型混用
20n + "20"
// 2020 
// 不過卻能跟字串結合,而且是轉成數字之後再跟字串結合

如果要bigint 跟 number 做運算則必須轉成同一類型

不過如果要將bigint轉成number有可能會喪失部分的精度

所以比較推薦都轉成bigint去做運算

另外bigint顧名思義就是大數字,所以他不負責處理小數的部分

有小數的值無法轉成bigint,而bigint運算出有小數的結果都會無條件捨去小數的值

7n/4n
// 1n 小數點後面直接捨去

bigint是少數在四則運算中不會自動轉型的一個型別

但是如果拿 bigint 跟 number 做比較

會發現他們是可以被比較的

1n < 2
// true
1n == 1
// true 
1n === 1
// false
// 因為透過轉型,他們是不完全相等但是不是完全相等

鯊語錄

boolean(布林值、布爾值)

boolean他代表著truth(真實)或是falsehood(虛假),

常用來表示判斷/比較的結果,而他的值只有兩個true(真實)跟false(錯誤),

也是if/else述句常出現的判斷基準或是for迴圈的執行與終止的條件。

特別注意:

數字的0跟空字串""會自動轉型成boolean的false

數字的1會自動轉型成boolean的true

這些小細節可以好好的運用在if/else述句上面

可以剩下很多判斷的功夫

結語

曾經Chris說過,如果想要學得快就自己學

如果想學的久,就大家陪你一起學

你們願意陪鯊魚一起學習一起成長嗎?

基礎是一個重要但是很無趣的東西

而且一隻鯊魚能看到的東西相當有限

如果有遺漏的地方,還請大家多多指點我

讓我們一起走得更遠。

參考資料

MDN-NaN
wiki-雙精度浮點數
MDN-boolean
MDN-BigInt


上一篇
想轉職的鯊魚從零基礎開始學習JavaScript Day-05 型別 Primitive type及string字串淺談
下一篇
想轉職的鯊魚從零基礎開始學習JavaScript Day-07 null、undefined及symbol
系列文
想轉職的鯊魚從零基礎開始學習JavaScript31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
jadddxx
iT邦新手 5 級 ‧ 2022-09-21 19:28:50

鯊魚二號

我要向世界宣揚鯊魚的美好

我要留言

立即登入留言